package com.jshan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jshan.base.entity.SysMenu;
import com.jshan.base.entity.SysRoleMenu;
import com.jshan.base.entity.SysUserRole;
import com.jshan.mapper.SysMenuMapper;
import com.jshan.mapper.SysRoleMenuMapper;
import com.jshan.mapper.SysUserRoleMapper;
import com.jshan.service.SysMenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    private final SysUserRoleMapper userRoleMapper;
    private final SysRoleMenuMapper roleMenuMapper;
    private final SysMenuMapper menuMapper;

    @Override
    public List<SysMenu> getMenuListByUserId(Long userId) {
        // 1. 查用户所有角色
        List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        if (userRoles.isEmpty())
            return Collections.emptyList();
        List<Long> roleIds = userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        // 2. 查角色所有菜单
        List<SysRoleMenu> roleMenus = roleMenuMapper.selectList(
                new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds));
        if (roleMenus.isEmpty())
            return Collections.emptyList();
        List<Long> menuIds = roleMenus.stream().map(SysRoleMenu::getMenuId).distinct().collect(Collectors.toList());
        // 3. 查菜单详情
        List<SysMenu> menus = menuMapper.selectBatchIds(menuIds).stream().filter(r -> r.getStatus() == 1).collect(Collectors.toUnmodifiableList());
        // 4. 构建菜单树 (只包含目录和菜单类型，不包含按钮)
        return buildUserMenuTree(menus, 0L);
    }

    @Override
    public IPage<SysMenu> getMenuPage(IPage<SysMenu> page, String menuName) {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(menuName)) {
            wrapper.like(SysMenu::getName, menuName);
        }
        return menuMapper.selectPage(page, wrapper);
    }

    @Override
    public boolean hasChildren(Long menuId) {
        return menuMapper.selectCount(
                new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId)) > 0;
    }

    @Override
    public List<SysMenu> getAllMenus() {
        List<SysMenu> allMenus = menuMapper.selectList(null);
        return buildAllMenuTree(allMenus, 0L);
    }

    // 构建用户菜单树 (不包含按钮，用于侧边栏导航)
    private List<SysMenu> buildUserMenuTree(List<SysMenu> menus, Long parentId) {
        List<SysMenu> tree = new ArrayList<>();
        for (SysMenu menu : menus) {
            // 只有当是父菜单的子节点且不是按钮类型时，才添加到菜单树中
            if (Objects.equals(menu.getParentId(), parentId) && !"F".equals(menu.getType())) {
                List<SysMenu> children = buildUserMenuTree(menus, menu.getId());
                menu.setChildren(children);
                tree.add(menu);
            }
        }
        tree.sort(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo)));
        return tree;
    }

    // 构建所有菜单树 (包含按钮，用于权限分配)
    private List<SysMenu> buildAllMenuTree(List<SysMenu> menus, Long parentId) {
        List<SysMenu> tree = new ArrayList<>();
        for (SysMenu menu : menus) {
            // 包含所有类型，只需判断父子关系
            if (Objects.equals(menu.getParentId(), parentId)) {
                List<SysMenu> children = buildAllMenuTree(menus, menu.getId());
                menu.setChildren(children);
                tree.add(menu);
            }
        }
        tree.sort(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo)));
        return tree;
    }
}
